import math, gtk, Point, Shape, Spec


class DrawingController:
	
	def __init__(self, drawing_area):
		self.all_shapes = [] # all the shapes to br draw
		self.selected = [] # all the selected shapes
		self.drawing_area = drawing_area	
		self.shape_finished = True
		self.selected_spec = Spec.Spec()
		self.set_up_selected_spec()
		self.w = [50,50,680,250]
		
	def set_up_selected_spec(self):
		self.selected_spec.trace = None
		self.selected_spec.double = True
		self.selected_spec.intensity = 65535
		self.selected_spec.color = [True, False, False]

	def draw(self, spec,save):
		""" Take a specification Spec to know which shape to add to self.all_shapes"""
		if spec.shape == "Line":
			self.shape = Shape.Line(spec.points[0], spec.points[1], self.drawing_area.window, spec)	
		elif spec.shape == "Circle" or (spec.shape == "Regular" and not save):
			self.shape = Shape.Circle(spec.points[0], spec.points[1], self.drawing_area.window, spec, save)
		elif spec.shape == "Polygon":
			if self.shape_finished:
				self.shape = Shape.Polygon(spec.points[-2], spec.points[-1], self.drawing_area.window, spec)
			else:
				self.shape.add_point(spec.points[-1], save)
		elif spec.shape == "Regular":
			self.shape = Shape.Regular(spec.points[0], spec.points[1], self.drawing_area.window, spec)
		elif spec.shape == "Arrow":
			self.shape = Shape.Arrow(spec.points[0], spec.points[1], self.drawing_area.window, spec)

		self.repaint(save)
		if self.shape == None: # error or clear all. Bug fixing of moving window
			return True
		self.shape_finished = self.shape.draw(save,self.w)
		if(save and self.shape.finished):
			self.all_shapes.append(self.shape)
		return self.shape_finished


	def save_shapes(self):
		arq = open("save.txt","a")
		for s in self.all_shapes:
			s.print_spec(arq)
		arq.close()
	
	def clear_all(self):
		""" Clear the dwaing_area """
		self.all_shapes = []
		self.selected = []
		self.shape = None
		self.shape_finished = True
		self.repaint(True)

	def fill_all(self,spec, save):
		gc = self.drawing_area.window.new_gc()
		(red,green,blue) = (65535*x for x in spec.color)
		gc.set_rgb_fg_color(gtk.gdk.Color(red,green,blue))
	  	for s in self.selected:
			s.fill(gc)
		self.repaint(save)

	def translate_all(self,save,points, to_repaint = True):
		dx = points[1].x-points[0].x
		dy = points[1].y-points[0].y		
		for s in self.selected:
			s.translate(dx,dy)	
		if to_repaint:
			self.repaint(save)
		return True

	def rotate_all(self,save,angle,center, to_repaint = True):
		for s in self.selected:
			s.rotate(save,angle,center)
		if to_repaint:
			self.repaint(save)
		return True

	def group_all(self,spec):
		shape = Shape.Shape(self.drawing_area.window, spec)	
		for s in self.selected[:]:
			self.selected.remove(s)
			self.all_shapes.remove(s)
			shape.shapes.append(s)
		self.selected.append(shape)
		self.all_shapes.append(shape)

	def ungroup_all(self,spec):
		for shape in self.selected[:]:
			self.all_shapes.remove(shape)
			self.selected.remove(shape)
			for s in shape.shapes:
				self.all_shapes.append(s)
				self.selected.append(s)
		
	def clear_screen(self):
		gc = self.drawing_area.window.new_gc()
		gc.set_rgb_fg_color(gtk.gdk.Color(35535,35535,35535))
		
		self.drawing_area.window.draw_rectangle(gc, True, 0, 0, 1500, 1500) # acochambrado/ colocar double buffering
		gc.set_rgb_fg_color(gtk.gdk.Color(65535,65535,65535))
		self.drawing_area.window.draw_rectangle(gc, True, self.w[0], self.w[1], self.w[2]-self.w[0], self.w[3]-self.w[1]) # acochambrado/ colocar double buffering
		
	
	def repaint(self, save = True):
		""" Repaint all_shapes in drawing_area """
		self.clear_screen()
		for s in self.all_shapes:
			s.draw(save,self.w)
		
	def select(self, point, continue_selecting):
		if not continue_selecting:
			self.free_selected()
		same = False
		size = len(self.selected)
		for s in self.all_shapes:
			if s.hasPoint(point):
				same = self.__putInSelected(s)
		#If the point selected do not belongs to any shape the selection is finished
		if not same and size == len(self.selected):
			self.free_selected()
			
		return len(self.selected) > 0
	
	#Tries to put a new shape in selected. If it already is in selected return True
	def __putInSelected(self, shape):
		for s in self.selected:
			if s == shape:
				return True
		self.selected.append(shape)
		shape.change_gc(self.selected_spec,True)
		shape.draw(True,self.w)
		return False
	
	def free_selected(self):
		for s in self.selected:
			s.back_old_gc()
		self.selected = []
		self.repaint()
		
	def change_selected(self, spec):
		for s in self.selected:
			s.change_gc(spec)
			s.change_gc(self.selected_spec, True)
		self.repaint()
	
	def delete_selected(self):
		for s in self.selected[:]:
			self.all_shapes.remove(s)
			self.selected.remove(s)
		self.repaint()
	
	def reflect_by(self, spec):	
		origin = Point.Point(0,0)
		# translate
		points = [spec.points[0], origin]
		self.translate_all(False, points, False)
		# Rotate
		spec.points[1] -= spec.points[0]
		angle = math.atan2(spec.points[1].y, spec.points[1].x)
		self.rotate_all(False, angle, origin, False)
		# Simple reflection
		for s in self.selected:
			 s.simple_reflect()
		#Go back!		
		self.rotate_all(False, -angle, origin, False)
		points = [origin, spec.points[0]]
		self.translate_all(True, points, True)
